#ifndef DFA_H_
#define DFA_H_

#include <iostream>
#include <ostream>
#include <set>
#include <string>
#include <iterator>
#include "Transition.h"

using namespace std;
namespace dfa {
	
template <class DataType> 
class Dfa
{
public:
	Dfa();
	Dfa(const DataType &startState, set<Transition<DataType> > &transition, set<DataType> &finalState);
	set<DataType> getLanguage(int maxSteps);
	set<DataType> getStates(const DataType &fromState, const char &currentChar);
	void getWords(int maxSteps, DataType &state, const string &word, set<DataType> & result);
	bool isEndState(const DataType &state);
	bool acceptString(const string &word);
	virtual ~Dfa();
	
	friend ostream& operator <<(ostream &os,const Dfa<DataType> &data)
	{
		os << "Alphabet: ";
		copy(data.symbols.begin(), data.symbols.end(), ostream_iterator<const char>(cout, " "));
		os << endl;
		os << "States: ";
		copy(data.states.begin(), data.states.end(), ostream_iterator<const string>(cout, " "));
		os << endl;
		os << "Start state: " << *data.startStates.begin() << endl;
		os << "End states: ";
		copy(data.finalStates.begin(), data.finalStates.end(), ostream_iterator<const string>(cout, " "));
		os << endl;
		os << "Transitions: ";
		copy(data.transitions.begin(), data.transitions.end(), ostream_iterator<const Transition<DataType> >(cout, " "));
		os << endl;
		return os;
	}
		
private:
	set<Transition <DataType> > transitions; 
	set<DataType> states;
	set <DataType> startStates;
	set<DataType> finalStates;
	set<char> symbols;
	set<DataType> result;
};
#include "Dfa.cpp"
}
ostream& operator <<(ostream& os, const set<string> &exp);
#endif
